/***********************************************************************************
 * 文件名： smcp_common.h
 * 作者： 刘言
 * 版本： 4.1
 * 说明：
 * 		SMCP通用内容。
 * 修改记录：
 * 	2024/2/1: 初版。 刘言。
***********************************************************************************/
#ifndef _SMCP_COMMON_H_
#define _SMCP_COMMON_H_

#include "smcp_config.h"
#include "polsys.h"

// 自定义类型

// 事件
typedef enum _smcp_event
{
    SMCP_EV_RECEIVED_PKG,   // 收到了一包数据，且数据已被解密（可用）
    SMCP_EV_TIME_OUT,       // 一包数据接收到一半，然后超时了
    SMCP_EV_CHECK_ERROR,    // 一包数据收完了，但是数据包校验未通过（数据有错误）
    SMCP_EV_AUTH_ERROR,     // 一包数据收完了，但是认证码错误（主机是仿品）
    SMCP_EV_BACK_ERROR,     // 一包数据收完了，但是回应码错误（从机是仿品）
    SMCP_EV_BUS_ERROR,      // 总线错误，一般是出现了2个主机
    SMCP_EV_BUFF_FULL       // 缓存满了（此事件在中断线程传递），必须复制出数据，不然会被覆盖
}smcp_event_t;

// 事件回调函数类型
typedef void (*smcp_callback_t)(smcp_event_t e);

// 主机READ命令的数据格式
typedef struct _smcp_read
{
    u8 Cmd;
    u8 Reserved;
    u16 Addr;
    u16 Length;
}smcp_read_t;

// 主机LREAD命令的数据格式
typedef struct _smcp_lread
{
    u8 Cmd;
    u8 Reserved[3];
    u32 Addr;
    u16 Length;
}smcp_lread_t;

// 主机WRITE命令的数据格式
typedef struct _smcp_write
{
    u8 Cmd;
    u8 Reserved;
    u16 Addr;
    u8 Data[];    // 要写入的数据
}smcp_write_t;

// 主机LWRITE命令的数据格式
typedef struct _smcp_lwrite
{
    u8 Cmd;
    u8 Reserved[3];
    u32 Addr;
    u8 Data[];  // 要写入的数据
}smcp_lwrite_t;

// 主机ANTI命令的数据格式
typedef struct _smcp_anti
{
    u8 Cmd;
    u8 Reserved[3];
    u8 Rand[4];
}smcp_anti_t;

// 主机ERASE命令的数据格式
typedef struct _smcp_erase
{
    u8 Cmd;
    u8 Reserved[3];
    u32 Addr;
    u32 Length;
}smcp_erase_t;

// 主机SetBaud命令的数据格式
typedef struct _smcp_set_baud
{
    u8 Cmd;
    u8 Act;
    u8 Reserved[2];
    u32 Baud;
}smcp_set_baud_t;

// 命令列表
typedef enum _smcp_cmd
{
    SMCP_CMD_READ = 0x12,
    SMCP_CMD_LREAD = 0X13,
    SMCP_CMD_WRITE = 0X14,
    SMCP_CMD_LWRITE = 0X15,
    SMCP_CMD_PRIVILEGE = 0X16,
    SMCP_CMD_ANTI = 0X17,   // 防伪，内部处理
    SMCP_CMD_UPDATE = 0xD0,
    SMCP_CMD_ERASE = 0XD1,
    SMCP_CMD_SET_BAUD = 0XD2,
    SMCP_CMD_RETURN = 0XFE
}smcp_cmd_t;

// return命令的错误码类型定义
typedef enum _smcp_rt
{
    SMCP_RT_SUCCEED = 0x00, // 操作成功
    SMCP_RT_PARAM_ERR,
    SMCP_RT_UNKNOW_CMD,
    SMCP_RT_TIMEOUT,
    SMCP_RT_ST_ERR,
    SMCP_RT_NO_MEM,
    SMCP_RT_SLAVE_IN = 0X10,
    SMCP_RT_PART_PKG = 0xFF
}smcp_rt_t;

typedef enum _smcp_role
{
    SMCP_ROLE_HOST = 0,
    SMCP_ROLE_SLAVE
}smcp_role_t;


/**
 * 把4字节数据通过一系列运算得出8字节数据
 * @param scr 4字节输入数据
 * @param dst 8字节输出数据
*/
void Smcp_Encrypt(const u8 *scr, u8 * dst);

#endif

